home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / glx / util.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  9KB  |  340 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  * 1993 Simon Hui -- Silicon Graphics Computer Systems
  19.  */
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <stdlib.h>
  23. #include <GL/gl.h>
  24. #include <GL/glx.h>
  25. #include <X11/keysym.h>
  26. #include "util.h"
  27.  
  28. static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
  29. {
  30.     if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
  31.     return GL_TRUE;
  32.     }
  33.     return GL_FALSE;
  34. }
  35.  
  36. Window utilCreateWindow( int defW, int defH, int defX, int defY, Window parent,
  37.              int attributes[], char *colorName,
  38.                  int argc, char **argv, char *geometry,
  39.              Display **dpy_ret, XVisualInfo **vi_ret,
  40.              Colormap *cmap_ret, GC *xgc_ret )
  41. {
  42.     Display *dpy;
  43.     Window window;
  44.     XVisualInfo *vi;
  45.     Colormap cmap;
  46.     GC xgc;
  47.     XSetWindowAttributes swa;
  48.     unsigned int width, height;
  49.     XGCValues gcvalues;
  50.     XColor xcolor, exact;
  51.     XSizeHints sh;
  52.     XEvent event;
  53.  
  54.     if (dpy_ret && *dpy_ret) {
  55.     dpy = *dpy_ret;
  56.     } else {
  57.     dpy = XOpenDisplay(0);
  58.     if (!dpy) {
  59.         fprintf(stderr, "Can't connect to display \"%s\"\n",
  60.             getenv("DISPLAY"));
  61.         exit(1);
  62.     }
  63.     }
  64.  
  65.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributes);
  66.     if (!vi) {
  67.     fprintf(stderr, "Cannot find visual on \"%s\"\n",
  68.         getenv("DISPLAY"));
  69.     exit(1);
  70.     }
  71.  
  72.     if (cmap_ret && *cmap_ret) {
  73.     cmap = *cmap_ret;
  74.     } else {
  75.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
  76.                    AllocNone);
  77.     }
  78.     if (colorName) {
  79.     if (!XAllocNamedColor(dpy, cmap, colorName, &exact, &xcolor)) {
  80.         fprintf(stderr, "Can't allocate color %s for X\n", colorName);
  81.         exit(1);
  82.     }
  83.     swa.background_pixel = xcolor.pixel;
  84.     } else {
  85.     swa.background_pixel = 0;
  86.     }
  87.     swa.border_pixel = 0;
  88.     swa.colormap = cmap;
  89.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
  90.     | KeyReleaseMask;
  91.  
  92.     width = defW;
  93.     height = defH;
  94.     sh.x = defX;
  95.     sh.y = defY;
  96.     if (geometry) {
  97.     int x, y;
  98.     unsigned int w, h;
  99.     int mask = XParseGeometry(geometry, &x, &y, &w, &h);
  100.     if (mask & XValue)    sh.x = x;
  101.     if (mask & YValue)    sh.y = y;
  102.     if (mask & WidthValue)     width = w;
  103.     if (mask & HeightValue)    height = h;
  104.     }
  105.     sh.flags = USPosition | PPosition;
  106.     if (parent == None) parent = RootWindow(dpy, vi->screen); 
  107.     window = XCreateWindow(dpy, parent, sh.x, sh.y,
  108.                width, height,
  109.                0, vi->depth, InputOutput, vi->visual,
  110.                CWBorderPixel|CWColormap|CWEventMask|CWBackPixel,
  111.                &swa);
  112.     XSetStandardProperties(dpy, window, argv[0], argv[0],
  113.                None, argv, argc, &sh);
  114.     XSetWMColormapWindows(dpy, window, &window, 1);
  115.     XMapWindow(dpy, window);
  116.     XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
  117.  
  118.     if (!xgc_ret || !*xgc_ret) {
  119.     gcvalues.background = xcolor.pixel;
  120.     gcvalues.foreground = xcolor.pixel;
  121.     xgc = XCreateGC(dpy, window, GCForeground|GCBackground, &gcvalues);
  122.     }
  123.  
  124.     if (dpy_ret) *dpy_ret = dpy;
  125.     if (vi_ret) *vi_ret = vi;
  126.     if (cmap_ret) *cmap_ret = cmap;
  127.     if (xgc_ret) *xgc_ret = xgc;
  128.  
  129.     return window;
  130. }
  131.  
  132.  
  133. void utilEventLoop( Display *dpy,
  134.             void (*exposeCallback)(void),
  135.             void  (*keyCallback)( KeySym, Bool *exit, Bool *redraw),
  136.             void (*displayCallback)(void) )
  137. {
  138.     XEvent event;
  139.     Bool redraw = False;
  140.     
  141.     for (;;) {
  142.     do {
  143.         XNextEvent(dpy, &event);
  144.         switch (event.type) {
  145.           case Expose:
  146.         if (exposeCallback) {
  147.             (*exposeCallback)();
  148.         } else {
  149.             (*displayCallback)();
  150.         }
  151.         break;
  152.           case KeyPress:
  153.         {
  154.             char buf[100];
  155.             int rv;
  156.             KeySym ks;
  157.             Bool exit = False;
  158.  
  159.             rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
  160.             (*keyCallback)(ks, &exit, &redraw);
  161.             if (exit) return;
  162.         }
  163.         break;
  164.         }
  165.     } while (XPending(dpy) != 0);
  166.     if (redraw) {
  167.         (*displayCallback)();
  168.         redraw = False;
  169.     }
  170.     }
  171. }
  172.  
  173. /*------ routines for prompting user ---------------------------------------*/
  174.  
  175. void utilPromptUser( void )
  176. {
  177.     char buf[20];
  178.  
  179.     printf( "Hit return for next frame: ");
  180.     gets(buf);
  181. }
  182.  
  183. /*------ routines for reading images ---------------------------------------*/
  184.  
  185. #include <gl/image.h>
  186.  
  187. void utilDumpRGBImage( char *fname, int width, int height, char *buf )
  188. {
  189.     IMAGE *image;
  190.     int sz=width*height*3;
  191.     int x, y, i;
  192.     short *rbuf, *gbuf, *bbuf;
  193.     char fullname[40];
  194.  
  195.     sprintf( fullname, "%s.img", fname );
  196.     if ((image=iopen( fullname, "w", RLE(1), 3, width, height, 3)) == NULL) {
  197.     fprintf(stderr,"iopen: can't open input file %s", fullname);
  198.     exit(1);
  199.     }
  200.     rbuf = (short *)malloc(width*sizeof(short));
  201.     gbuf = (short *)malloc(width*sizeof(short));
  202.     bbuf = (short *)malloc(width*sizeof(short));
  203.  
  204.     for (y=0; y < height; y++) {
  205.     for (x=0; x < width; x++) {
  206.         i = (y*width + x)*3;
  207.         rbuf[x] = buf[i];
  208.         gbuf[x] = buf[i+1];
  209.         bbuf[x] = buf[i+2];
  210.     }
  211.     putrow( image, rbuf, y, 0 );
  212.     putrow( image, gbuf, y, 1 );
  213.     putrow( image, bbuf, y, 2 );
  214.     }
  215.     iclose( image );
  216.     free( rbuf );
  217.     free( gbuf );
  218.     free( bbuf );
  219. }
  220.  
  221. void write_asc_file( char *fname, int width, int height, unsigned char *buf )
  222. {
  223.     FILE *fp;
  224.     int sz=width*height*3;
  225.     int x, y, i, n;
  226.     char fullname[40];
  227.     unsigned long p;
  228.  
  229.     sprintf( fullname, "%s.asc", fname );
  230.     if (!(fp = fopen( fullname, "w"))) {
  231.     fprintf(stderr,"fopen: can't open input file %s", fullname);
  232.     exit(1);
  233.     }
  234.     n = 0;
  235.     for (y=0; y < height; y++) {
  236.     fprintf( fp, "\nline %2d\n", y );
  237.     for (x=0; x < width; x++) {
  238.         i = (y*width + x)*3;
  239.         p = buf[i+2];
  240.         p <<= 8;
  241.         p |= buf[i+1];
  242.         p <<= 8;
  243.         p |= buf[i];
  244.         fprintf (fp, "%8x ", p);
  245.  
  246.         n++;
  247.         if (!(n % 8)) fprintf( fp, "\n" );
  248.     }
  249.     }
  250.     fclose( fp );
  251. }
  252.  
  253. /*---- Find graphics board type (stolen from ogtst) ----------------------*/
  254.  
  255. void utilGetGraphicsName( char *glrenderer, char *buf )
  256. {
  257.     char a[32],b[32],c[32],d[32];
  258.  
  259.     /* REALITY ENGINE/VTX */
  260.     if (!strncmp("RE", glrenderer, 2) || !strncmp("VTX", glrenderer, 3)) {
  261.     sscanf(glrenderer,"%[^/]%*c%[^/]%*c%[^/]%*c%1s",a,b,c,d);
  262.     strcpy(buf, "RE");
  263.     strcat(buf, c);
  264.     }
  265.  
  266.     /* EXPRESS */
  267.     else if (!strncmp("GR2-Elan", glrenderer, 8) ||
  268.          !strncmp("GR2EV-Extreme", glrenderer, 13) ||
  269.          !strncmp("GU1-Extreme", glrenderer, 11) ||
  270.          !strncmp("GR2-XZ", glrenderer, 6)) {
  271.     strcpy(buf, "XG24");
  272.     }
  273.  
  274.     /* STARTER */
  275.     else if (!strncmp("LIGHT", glrenderer, 5) ||
  276.          !strncmp("LG1MC", glrenderer, 5)) {
  277.     strcpy(buf, "LG");
  278.     }
  279.  
  280.     /* NEWPORT */
  281.     else if (!strncmp("NEWPORT", glrenderer, 7)) {
  282.     strcpy(buf, "NG24");
  283.     }
  284.  
  285.     else {
  286.     printf( "unexpected GL_RENDERER string\n" );
  287.     exit (1);
  288.     }
  289. }
  290.  
  291. /*---- Misc ---------------------------------------------------------------*/
  292.  
  293. /*
  294. ** Get the X pixel value for a 3-component color.
  295. */
  296. unsigned long utilXPixel(float r, float g, float b, XVisualInfo *vi)
  297. {
  298.     unsigned long rmask, gmask, bmask;
  299.     unsigned long rmax, gmax, bmax;
  300.     int rshift, gshift, bshift;
  301.     unsigned long pixel;
  302.  
  303.     if (vi->class != TrueColor && vi->class != DirectColor) {
  304.     fprintf( stderr, "PixelOf: visual has wrong class\n");
  305.     exit(1);
  306.     }
  307.     /*
  308.     ** Count the number of shifts for each component.
  309.     */
  310.     rmask = vi->red_mask;
  311.     for (rshift=0; !(rmask & 1); rshift++) rmask >>= 1;
  312.     gmask = vi->green_mask;
  313.     for (gshift=0; !(gmask & 1); gshift++) gmask >>= 1;
  314.     bmask = vi->blue_mask;
  315.     for (bshift=0; !(bmask & 1); bshift++) bmask >>= 1;
  316.  
  317.     rmax = vi->red_mask >> rshift;
  318.     gmax = vi->green_mask >> gshift;
  319.     bmax = vi->blue_mask >> bshift;
  320.     r = (r >= 1 ? rmax : r*(rmax+1));
  321.     g = (g >= 1 ? gmax : g*(gmax+1));
  322.     b = (b >= 1 ? bmax : b*(bmax+1));
  323.     pixel = (((unsigned long)r << rshift) |
  324.              ((unsigned long)g << gshift) |
  325.              ((unsigned long)b << bshift));
  326.     return pixel;
  327. }
  328.  
  329. /*
  330.  * Useful for debugging.
  331.  */
  332. void utilCheckError(void)
  333. {
  334.     GLenum error = glGetError();
  335.     if (error) {
  336.     fprintf (stderr, "error found: %x\n", error);
  337.     }
  338. }
  339.  
  340.